从 Shapley 到 SHAP — 数学理解

如何计算 SHAP 特征贡献的概述

img{:width 100} 假设你(玩家 1)和朋友(玩家 2)参加了一场 Kaggle 比赛,你最终赢得了 10,000 元的一等奖。现在,你想公平地分配这笔钱。你的朋友建议你平分。但是,你的超参数调整技能更出色。你相信你应该得到更大的份额,因为你为团队做出了更多贡献。考虑到这一点,你如何公平地分配这笔钱?

巧合的是,你的朋友有一台时光机。你们各自回到过去,单独重赛 Kaggle 比赛。你最终获得第二名,获得 7,500 元。你的朋友只获得第三名,获得5,000 元。如果你们都没有参赛,你们就不会获得任何奖金(0 元)。我们记录了以下这 4 个玩家团队的价值。显然,你应该获得更多奖金,但目前还不清楚如何分配奖金。

\[ \begin{align*} C_{12} & = 10,000 \\ C_1 & = 7,500 \\ C_2 & = 5,000 \\ C_0 & = 0 \end{align*} \]

一种方法是计算每个玩家的预期边际贡献。这是玩家对其可能加入的所有团队的贡献的加权平均值。

例如,玩家 1 (P1) 可以加入只有玩家 2 (P2) 的团队。P2 从第三名升至第一名,奖金增加$5000。P1 也可以加入没有玩家的团队,奖金增加 $7,500。这些是 P1 的边际贡献。这些的平均值给出了预期边际贡献 $6,250。

\[ \begin{align*} C_{12} C_2 = 5,000 \\ C_1 C_0 = 7,500 \\ (5,000 + 7,500) / 2 = 6,250 \end{align*} \]

我们可以按照类似的过程来计算 P2 的预期边际贡献。这次的值为 3,750 元。最终,P1 将获得 6,250 元,P2 将获得 3,750 元。这两个值也称为 Shapley 值。请注意,这些值加起来的总奖金为 10,000 元。

\[ \begin{align*} C_{12} C_1 = 2,500 \\ C_2 C_0 = 5,000 \\ (2,500 + 5,000) / 2 = 3,750 \end{align*} \]

Shapley 值被认为是一种公平的奖金分配方式,这是一个来自博弈论的概念。我们只为 2 名队员的团队计算了 Shapley 值。我们能够使用它们来计算任何规模团队的公平分配。我们将花时间理解这个广义的 Shapley 值公式。这个公式可能看起来很吓人。然而,当我们深入了解时,你会发现它有一个直观的解释。

Shapley 值 = 预期边际贡献

这是玩家对其可以加入的所有团队的贡献的加权平均值。 从分配奖金到解释机器学习模型,这似乎是一个巨大的飞跃。然而,Shapley 值可用于了解每个模型特征(玩家)对预测(奖金)的贡献。我们将解释如何扩展 Shapley 值来解释模型预测。最后,我们将探讨 SHAP 对这一研究领域的贡献。也就是说,它们大大提高了我们近似 Shapley 值的速度。

3 人游戏的 Shapley 值

在继续之前,让我们先看另一个例子。这将使一般方程更容易理解。这次我们的队伍有 3 名球员。计算很复杂,我们得再回溯几次。 现在将有 8 个可能的团队,如下所示。你们一起赢得一等奖(10,000 元)。现在有 3 个由 2 名玩家组成的团队。例如,P1 和 P3 组成的团队将获得第二名(7,500 元)。还会有 1 名玩家组成的团队。例如,如果 P3 单独比赛,他将不会获得任何奖金(0 元)。也许他应该投资购买更好的 GPU。

\[ \begin{align*} & C_{123} = 10,000 && C_{12} = 7,500 && C_1 = 5,000 \\ & C_0 = 0 && C_{13} = 7,500 && C_2 = 5,000 \\ & && C_{23} = 5,000 && C_3 = 0 \end{align*} \]

我们可以使用这些团队值来计算 P1 的 Shapley 值。现在 P1 可以加入 4 个团队。P1 可以加入 P2 和 P3 的团队、只有 P2 或 P3 的团队或没有参与者的团队。像以前一样,我们计算 P1 对每个团队的边际贡献。最后,我们取加权平均值。这给了我们 Shapley 值 5,000 元。

\[ \begin{align*} & C_{123} C_{23} = 5,000 \\ & C_{12} C_2 = 2,500 \\ & C_{13} C_3 = 7,500 \\ & C_1 C_0 = 5,000 \\ & 5,000 \times \frac{1}{3} + 2,500 \times \frac{1}{6} + 7,500 \times \frac{1}{6} + 5,000 \times \frac{1}{3} = 5,000 \end{align*} \]

你可能会问,我们从哪里得到这些权重?这就是为什么我们要将第一个边际贡献的权重设为 1/3,将第二个边际贡献的权重设为 1/6,依此类推……这些是 P1 做出这些特定贡献的概率。按概率加权可以得到预期边际贡献。

这些概率的来源并不明显。首先,我们需要计算出组成 3 人团队的方法数量。这是因为只有所有 3 名成员共同努力,才能赢得全部奖金(10,000 元)。

为此,我们假设每个成员以平等的机会依次加入团队。例如,P1 加入,然后 P3 加入,然后 P2 加入。这给了我们总共 3! = 6 种组建团队的方法。你可以在下面看到所有这些方法。一般来说,有 n! 种方法可以组建一支由 n 名球员组成的团队。

\[ \begin{align*} C_0 \to C_1 \to C_{12} \to C_{123} \\ C_0 \to C_1 \to C_{13} \to C_{132} \\ C_0 \to C_2 \to C_{21} \to C_{213} \\ C_0 \to C_2 \to C_{23} \to C_{231} \\ C_0 \to C_3 \to C_{31} \to C_{312} \\ C_0 \to C_3 \to C_{32} \to C_{321} \\ \end{align*} \]

上面我们看到,如果 P1 加入 P2 和 P3 的团队,他将做出 5000 元的边际贡献。这可能以两种方式发生。要么 P2 加入,然后 P3 加入,然后 P1 加入,要么 P3 加入,然后 P2 加入,然后 P1 加入。换句话说,在 6 种团队组建方式中,P1 将为其中 2 种做出这一边际贡献。这给了我们 P1 做出这一贡献的概率为 2/6 = 1/3。

P1 做出第二种贡献( 2,500 )的方式只有一种。即如果 P2 加入,然后 P1 加入,然后 P3 加入。这样得到的概率为 1/6。同样,第三种贡献(7,500)的概率为 1/6。第四笔贡献(5,000)的概率为 1/3。与第一笔贡献一样,P1 做出贡献的方式也有两种。首先 P1 加入,然后 P2 加入,然后 P3 加入,或者 P3 加入,然后 P2 加入。

我们可以对 P2 和 P3 执行相同的过程。对于这些玩家,Shapley 值分别为 3,750 元和 1,250 元。同样,所有 Shapley 值加起来等于总奖金。Shapley 值将始终公平地分配所有奖金。现在让我们看看如何概括 Shapley 值。

广义 Shapley 值

公式 1 给出了 p 人游戏中 玩家 i 的 Shapley 值的公式。从求和符号开始,我们对所有团队 S 求和。其中 S 是不包括玩家 i 的团队子集。换句话说,S 包含玩家 i 能够做出边际贡献的所有团队。回到 3 人游戏的例子,有 4 个团队不包括 P1。

等式 1:p 人游戏中第 i 名玩家的 shapley 值(来源:作者)

在方括号内,我们得到了玩家 i 对团队 S 的边际贡献。具体来说,我们得到了团队 S 的价值 (val),包括玩家 i 减去团队 S 的价值。价值函数取决于正在玩的特定游戏。在我们的 3 人示例中,我们使用了不同的符号。我们讨论了团队价值,并使用了带有玩家下标的字母 C。这些团队价值为 Kaggle 游戏提供了价值函数。 最后,我们对边际贡献进行加权。下面,你可以看到权重的每个组成部分代表什么。这里 |S| 是团队 S 中的玩家数量。这意味着 p-|S|-1 是在玩家 i 之后需要加入团队的玩家数量。

\[ \begin{align*} & |S|! \Rightarrow \textbf{玩家可以在玩家 i 之前加入 团队S 的方式数量} \\ & (p |S| 1)! \Rightarrow \textbf{玩家 i 加入后玩家加入团队 S 的方式数量}\\ & p! \Rightarrow \textbf{组建 P 玩家团队的方法数量} \end{align*} \]

在权重分子中,我们有团队 S 可以形成的方式数量。分母是整个团队可以形成的方式数量。因此,权重给出了当游戏中有 p 个玩家时,玩家 i 对规模为 |S| 的团队做出贡献的概率。如果你代入我们的 3 人游戏的值,你将获得与之前相同的权重。

分解 Shapley 值,你会发现它有一个直观的解释。我们用玩家 i 做出贡献的概率来加权所有玩家 i 的边际贡献。然后,我们将这些加权贡献加到玩家 i 可以加入的所有团队中。这给了我们一个预期边际贡献。使用这些值,我们可以将游戏的总价值分配给所有玩家。

直观地看,预期边际贡献似乎是一种公平的做法。我们考虑所有团队的贡献。这意味着我们要考虑玩家的个人贡献和玩家之间的互动。也就是说,一些玩家可以很好地合作,从而增加他们的共同价值。问题是,可能还有其他看似公平的分配价值的方法。我们需要证明 Shapley 值是公平的。

形状公理

Shapley 值其实是由 3 条公理推导出来的。我们只会总结它们,但它们也可以用数学来定义。这些公理可以被认为是公平的定义。因此,满足此定义的价值分配方法可以被认为是公平的。

对称性:如果两个玩家对所有团队的贡献相同,则认为他们可互换。如果两个玩家可互换,则必须给予他们游戏总价值的平等份额。

空玩家属性:如果玩家对所有团队的边际贡献为零,那么他们将不会获得任何总价值。

可加性:如果我们将两场游戏结合起来,那么玩家的整体贡献就是两场单独游戏贡献的总和。这个公理假设任何游戏都是独立的。 我们可以用数学证明 Shapley 值是唯一满足这 3 条公理的有效值。所谓有效,是指游戏的价值不会有任何剩余。归根结底,根据这一定义,Shapley 值是唯一公平的分配价值的方法。如此直观的公式竟然可以从 3 条简单的公理中推导出来,真是令人惊叹。

机器学习的 Shapley 值

我们可以使用 Shapley 值来了解模型如何做出预测。现在,游戏的值是模型预测。特征值是玩家。要清楚的是,玩游戏的不是特征,而是特定观察的特征值。但是,我们将这些称为特征。我们使用 Shapley 值来计算每个特征对预测的贡献。

例如,在之前的文章《[[Python 中的 SHAP 简介]]》中,我们训练了一个模型来预测鲍鱼的年龄。你可以在图 1 中看到特定观测值的 Shapley 值。这些值给出了平均预测年龄 E[f(x)] 与观测值的预测值 f(x) 之间的差异。例如,去壳重量的值使预测年龄增加了 1.81。我们将其称为特征的贡献。

图 1:SHAP 值的示例

为了计算这些,我们可以使用与之前相同的 Shapley 值公式。我们需要做的就是改变值函数。公式 2 给出了我们用于特定观测 x 的函数。这里 S 是特征值的联合,f 给出模型预测,模型有 p 个特征。S 的值是模型的预测在所有不属于 S 的特征上被边缘化。我们对 S 中的特征使用实际值。

\[ val_x(S) = \int f(x_1, ..., x_p) dP_{x\notin S} \]

我们实际上是在上面的方程中进行多重积分。为了对特征进行边缘化,我们将预测函数与特征值的概率进行积分。我们对 S 中的所有特征都执行此操作。为此,我们需要了解特征分布或使用经验分布。 上述公式中有很多活动部件。在本节的下一部分中,我们将讨论一个 ML 示例,以便更好地理解它。然后,我们将继续讨论如何为 ML近似 Shapley 值。在本节结束时,我们将讨论 Shapley 值的属性。这些属性遵循公理,我们将讨论它们在机器学习中的含义。

机器学习示例

假设我们想预测某人的收入。我们有两个特征 —— age(特征 1)和 degree(特征 2)。我们最终得到下面的模型 f。对于 age,我们假设该特征在 18 到 60 岁之间均匀分布。同样,对于 degree,我们假设某人拥有学位 (1) 和不拥有学位 (0) 的概率相等。对于我们的观察,我们有一个 20 岁且拥有学位的人。该模型将预测此人的收入为 5,000 元。

\[ \begin{align*} f(x_1, x_2) = 200x_1 + 1000 x_2 \\ age \to x_1 \in [18, 60] \\ degree \to x_2 \in {0, 1} \end{align*} \]

我们可以计算特征 2 {2} 对特征 1 的团队 S = {1} 的边际贡献。这可用于帮助计算特征 2 的 Shapley 值。换句话说,计算特征 2(degree = 1)对预测的贡献。

我们首先计算两个特征的联合值,S = {1,2}。这相对简单。S 包含两个特征,因此我们不必对任何特征进行边缘化。我们可以使用该特征的实际值。如下所示,这与此观察的预测相同。

\[ \begin{align*} val_x(\{1, 2\}) & = f(20, 1) \\ & = 200(20) + 1000(1) \\ & = 5000 \end{align*} \]

然后我们需要计算团队的值,S = {1}。在这种情况下,S 不包含 {2}。我们对特征 2 进行边缘化,并使用特征 1 的实际值。请记住,特征 2 不是连续的。要对特征的值进行边缘化,我们不需要使用积分。我们只需将每个值的预测乘以该值的概率(即 50%)相加即可。

\[ \begin{align*} val_x(\{1\}) & = \int f(20, x_2)dP_{x_2} \\ & = \sum_{i=0}^1f(20, i)P(x_2 = i) \\ & = (200(20) + 1000(0))(0.5) + (200(20) + 1000(1))(0.5) \\ & = 4500 \end{align*} \]

现在,我们可以计算特征 2 对 S={1} 的边际贡献。此贡献的权重的计算方式与标准 Shapley 值相同。为清楚起见,我们使用团队中的特征数量和特征值的总数。我们有 |S| = |{1}| = 1 和 p = 2。这给了我们 (1!)(0!)/2! = 1/2 的权重。

\[ \begin{align*} val_x(\{1,2\}) val_x(\{1\}) = 500 \end{align*} \]

这只为我们提供了特征 2 的 Shapley 值所需的部分计算。我们还需要计算特征 2 对 S={} 的边际贡献。为此,我们需要计算 S = {} 的值函数。这需要我们对两个特征的分布进行边缘化。

Shapely 值的近似值

计算精确的 Shapley 值需要耗费大量计算资源。在上面的例子中,我们只有两个特征。随着我们添加更多特征,可能的团队数量会呈指数级增长。实际上,只能近似 Shapley 值。

一种方法是使用蒙特卡罗采样。对于特征 i,我们将首先使用特征值 (+i) 计算预测。我们在没有值 (-i) 的情况下执行相同操作。也就是说,我们为特征 i 取一个随机值。其余特征值也都将随机采样。我们取这两个预测之间的差值。如下所示,我们执行此操作 M 次并找到所有这些差值的平均值。通过随机采样和平均,我们隐式地按特征的分布加权。

\[ \begin{align*} \hat \Phi_i = \frac{1}{M}\sum_{m=1}^M(f(x_{+i}^m) f(m_{-i}^m)) \end{align*} \]

上述过程仍然不切实际。我们可能需要许多样本才能获得 Shapley 值的合理近似值。这就是 SHAP 的作用所在。正如我们在之前讨论的那样,它是一种更快的近似 Shapley 值的方法。在继续讨论这一点之前,我们将在机器学习的背景下讨论 Shapley 值的属性。

Shapley 值的属性

Shapley 是解释预测的一种方法。它之所以流行,是因为它具有令人满意的特性。这些特性大多源于 Shapley 值的公理。 效率如上所述,Shapley 值是高效的。以前,这意味着游戏的全部价值由玩家分担。对于 ML,这意味着预测由特征分担。具体来说,Shapley 值满足以下等式。所有 Shapley 值与平均预测值之和等于观察值的预测。我们在图 1 中看到了这一点。

\[ \begin{align*} f(x) = \sum_{i=1}^p \Phi_i + E_X[f(X)] \end{align*} \]

另一种流行的局部解释方法是 LIME。相比之下,LIME 并不一定有效。计算出的权重不会加起来等于原始预测。对于 Shapley,我们知道每个特征对预测的贡献有多大。对于 LIME,我们只知道哪个特征对该预测最重要。

对称性:如果两个特征对所有团队做出相同的贡献,则它们将具有相同的 Shapley 值。

虚拟:如果特征永远不会改变预测,则其 Shapley 值为 0。换句话说,模型中未使用的特征不会具有 Shapley 值。

可加性:机器学习的 Shapley 值也是可加性的。这只适用于集成模型。在这种情况下,可以通过对集成中每个模型的 Shapley 值取加权平均值来计算总体 Shapley 值。其中权重将与赋予每个模型的预测的权重相同。例如,在随机森林中,每个决策树的预测都被赋予相同的权重。

一致性:此属性源自前 3 个属性。假设我们将模型从 M1 更改为 M2。如果某个特征现在比以前增加了预测,则其 Shapley 值将增加。这意味着我们可以可靠地比较不同模型的特征贡献。

SHAP 值

SHAP Python 包已成为处理 Shapley 值的代名词。该包被广泛实施的关键在于其进行近似的速度。我们将在下面讨论其中几种方法。速度的提高意味着我们还能计算许多 Shapley 值。这允许对值进行不同的聚合,从而让我们对模型有一个全局的了解。

KernelSHAP

KernelSHAP 将 Shapley 值重新定义为线性模型中的参数。简单地说,近似方法首先通过排列特征值来工作。经过足够的排列后,使用线性回归联合估计 Shapley 值。与其他采样方法相比,一起估计值需要更少的计算。例如蒙特卡罗采样,其中每个特征的 Shapley 值是单独计算的。

KernelSHAP 也是一种与模型无关的近似 Shapley 值的方法。这意味着它可以用于任何模型。前提是你的建模包已实施 SHAP。

TreeSHAP

TreeSHAP 是一种与模型无关的近似方法。它利用了集成模型中各个树的结构。因此,它只能与基于树的算法(如随机森林和 XGBoost)一起使用。TreeSHAP 的优势在于它比 KernelSHAP 快得多。

使用 KernelSHAP,我们可以在指数时间内估计 Shapley 值,相对于特征数量而言。而 TreeSHAP 可以在线性时间内估计它们。我们在文章《[[KernelSHAP vs TreeSHAP]]》中详细讨论了这一差异。还探讨了模型的其他方面如何影响近似时间。这包括集合中的树数、最大深度和叶子数。

如上所述,这些方法可以近似大量的 Shapley 值。我们可以以不同的方式组合它们,以了解整个模型的工作原理。一个例子是图 2 中给出的蜂群图。

在这里,我们将每个特征的值分组(例如壳重)。我们可以看到那些倾向于具有较大正 Shapley 值和负 Shapley 值的特征。这些特征往往对预测做出重大贡献。我们还根据特征的值对点进行着色。这样做我们可以开始了解特征和目标变量之间的关系。

图 2:蜂群图示例(来源:作者)


希望这篇文章对你有所帮助!你还可以阅读我的其他文章,或者查看有关企业 AI 实战项目的教程,相信会让你拥有更多收获。

「AI秘籍」系列课程: 人工智能应用数学基础

人工智能Python基础

人工智能基础核心知识

人工智能BI核心知识

人工智能CV核心知识

AI企业项目实战课优惠二维码

参考

S. Lundberg, SHAP Python package (2021), https://github.com/slundberg/shap

S. Lundberg & S. Lee, A Unified Approach to Interpreting Model Predictions (2017), https://arxiv.org/pdf/1705.07874.pdf

C. Molnar, Interpretable Machine Learning (2021) https://christophm.github.io/interpretable-ml-book/shap.html

S. Masís, Interpretable Machine Learning with Python (2021)

L.S. Shapley, Contributions to the Theory of Games, Chapter A Value for n-person Games. (1953)

Understanding The Shapley Value

Text S1: The Axiomatic Basis of the Shapley Value

从 Shapley 到 SHAP — 数学理解

https://hivan.me/从 Shapley 到 SHAP — 数学理解/

作者

Hivan Du

发布于

2024-09-27

更新于

2024-09-29

许可协议

评论